using System.Collections;
using System.IO;
using ThoughtWorks.TreeSurgeon.Core.Generators;
using ThoughtWorks.TreeSurgeon.Core.Generators.Content;

namespace ThoughtWorks.TreeSurgeon.Core
{
	public class SimpleTreeGenerator : IGenerator
	{
		private readonly ITransformingFileGenerator generator;
		private readonly IGuidGenerator guidGenerator;
		private readonly IDirectoryCopier directoryCopier;

		public SimpleTreeGenerator(IDirectoryCopier directoryCopier, ITransformingFileGenerator generator, IGuidGenerator guidGenerator)
		{
			this.generator = generator;
			this.guidGenerator = guidGenerator;
			this.directoryCopier = directoryCopier;
		}

		public void Generate(string projectName, string outputPath, string resourceBasePath)
		{
			directoryCopier.CopyDirectory(Path.Combine(resourceBasePath, Path.Combine("resources", "skeleton")), outputPath);

			Hashtable velocityContext = new Hashtable();
			velocityContext["projectName"] = projectName;
			velocityContext["nantDeleteClause"] = @"${directory::exists(build.dir)}";
			velocityContext["coreGuid"] = guidGenerator.GenerateGuid();
			velocityContext["unitTestGuid"] = guidGenerator.GenerateGuid();
			velocityContext["consoleGuid"] = guidGenerator.GenerateGuid();

			Generate(outputPath, "go.bat", "go.bat", velocityContext);
			Generate(outputPath, projectName + ".build", "Sapling.build", velocityContext);
			Generate(outputPath, "src\\" + projectName + ".sln", "Sapling.sln", velocityContext);
			Generate(outputPath, "src\\" + projectName + "Console\\" + projectName + "Console.csproj", "SaplingConsole.csproj", velocityContext);
			Generate(outputPath, "src\\" + projectName + "Console\\" + "AssemblyInfo.cs", "AssemblyInfo.cs", velocityContext);
			Generate(outputPath, "src\\" + projectName + "Console\\" + "HelloWorld.cs", "HelloWorld.cs", velocityContext);
			Generate(outputPath, "src\\Core\\" + "Core.csproj", "Core.csproj", velocityContext);
			Generate(outputPath, "src\\Core\\" + "AssemblyInfo.cs", "AssemblyInfo.cs", velocityContext);
			Generate(outputPath, "src\\UnitTests\\" + "UnitTests.csproj", "UnitTests.csproj", velocityContext);
			Generate(outputPath, "src\\UnitTests\\" + "AssemblyInfo.cs", "AssemblyInfo.cs", velocityContext);
			Generate(outputPath, "src\\UnitTests\\" + "Test1.cs", "Test1.cs", velocityContext);
		}

		private void Generate(string topPath, string childPath, string templateName, Hashtable velocityContext)
		{
			generator.Generate(Path.Combine(topPath, childPath), templateName + ".vm", velocityContext);
		}
	}
}